package org.jeecg.modules.simulator.model.line.station.station;

import lombok.Getter;
import lombok.Setter;
import org.jeecg.modules.simulator.jsonot.ODProbabilityApiInfo;
import org.jeecg.modules.simulator.jsonot.RouteStation;
import org.jeecg.modules.simulator.model.person.Person;
import org.jeecg.modules.simulator.model.person.path.PersonPath;
import org.jeecg.modules.simulator.model.person.path.PersonPathItem;

import java.util.*;

/**
 * @program: simulator-b20240918
 * @description: 历史数据加载
 * @author: renzhg
 * @create: 2024-10-24 09:43
 **/
public class LoadHistoryPerson implements LoadPerson {

    @Getter
    @Setter
    Map<String, Person> outsidePersonMap = new HashMap<>();
    @Setter
    Map<String, List<RouteStation>>  t80RouteHisMap;

    Map<String,Map<String, List<ODProbabilityApiInfo>>> odProbabilityApiInfosMapmap= new HashMap<>();
    @Setter
    Map<String, PersonPath> route2PersonPathMap = new HashMap<>();

    @Setter
    @Getter
    //换乘站集合
    Map<String, TransferStation> transferStationMap = new HashMap<>();//换乘站集合

    @Getter
    @Setter
    Map<String, Station> stationNetMap = new HashMap<>();



    public LoadHistoryPerson(Map<String,Map<String, List<ODProbabilityApiInfo>>> odProbabilityApiInfosMap,
                             Map<String, PersonPath> route2PersonPathMap
    ,Map<String, List<RouteStation>>  t80RouteHisMap,Map<String, Station> stationNetMap,Map<String, TransferStation> transferStationMap) {
        this.odProbabilityApiInfosMapmap = odProbabilityApiInfosMap;
        this.route2PersonPathMap = route2PersonPathMap;
        this.t80RouteHisMap = t80RouteHisMap;
        this.stationNetMap = stationNetMap;
        this.transferStationMap = transferStationMap;
    }

    /**
    * @description:
     * 该函数 loadHistoryPersons 用于根据传入的参数加载历史人员信息。具体功能如下：
     * 判断 odProbabilityApiInfosMap 的键数量是否超过 size：
     * 如果超过，则调用 addPersonsWhenExceedingSize 方法处理。
     * 否则，计算每个路由的信息量 infoSize，并调用 addPersonsBasedOnRouteRates 方法按比例添加人员。
     * 调用方法：
     * addPersonsWhenExceedingSize：处理超出大小的情况。
     * addPersonsBasedOnRouteRates：按比例分配人员
     *
     *
    *
    * @author: renzhg
    * @date: 2024/11/17 18:21
    **/
    public void loadHistoryPersons(int size,
                                   Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap,
                                   Map<String, PersonPath> route2PersonPathMap) {
        //路径概率机会数大于
        if (odProbabilityApiInfosMap.keySet().size() > size) {
            addPersonsWhenExceedingSize(size, odProbabilityApiInfosMap, route2PersonPathMap);
        }else{
            int infoSize = size / odProbabilityApiInfosMap.size();
            addPersonsBasedOnRouteRates(odProbabilityApiInfosMap, route2PersonPathMap, infoSize);
        }


    }
/**
* @description:
 * 添加人数，当人数超过添加要求的人数时退出，根据概率值排序，然后添加人数
*
* @author: renzhg
* @date: 2024/11/17 18:23
**/
    private void addPersonsWhenExceedingSize(int size,
                                             Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap,
                                             Map<String, PersonPath> route2PersonPathMap) {
        int count = 0;
        //根据概率值排序
        for (Map.Entry<String, List<ODProbabilityApiInfo>> entry : odProbabilityApiInfosMap.entrySet()) {
            //根据概率值排序
            Collections.sort(entry.getValue());
            //当添加书人数超过要添加的人数时，返回
            if (count >= size) {
                return;
            }

            addPersonForRoute(entry.getValue().get(0).getRouteId(), route2PersonPathMap);
            count++;
        }
    }

    private void addPersonsBasedOnRouteRates(Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap,
                                             Map<String, PersonPath> route2PersonPathMap,
                                             int infoSize) {
        for (Map.Entry<String, List<ODProbabilityApiInfo>> entry : odProbabilityApiInfosMap.entrySet()) {
            for (ODProbabilityApiInfo info : entry.getValue()) {
                String routeId = info.getRouteId();
                int result = calculatePersonCount(info.getRouteRate(), infoSize);
                for (int j = 0; j < result; j++) {
                    addPersonForRoute(routeId, route2PersonPathMap);
                }
            }

            // Add one more person for the first route in the current entry
            addPersonForRoute(entry.getValue().get(0).getRouteId(), route2PersonPathMap);
        }
    }

    private int calculatePersonCount(String routeRate, int infoSize) {
        double num = Double.parseDouble(routeRate) * 0.01 * infoSize;
        return (int) Math.floor(num);
    }


    /**
     * @description: 这个地方有问题，添加人的时候发现路径为空的时候，就直接返回了没有添加，
     * 所以这个人就没有添加进去，这个地方需要修改
     *
     * @author:  renzhg
     * @date:  2024/10/26 18:33
     **/
    private void addPersonForRoute(String routeId, Map<String, PersonPath> route2PersonPathMap) {


        if(route2PersonPathMap.containsKey(routeId)){
            PersonPath personPath = route2PersonPathMap.get(routeId);
            Person person = new Person(personPath);
            person.setId(UUID.randomUUID().toString());
            person.setInStationState();
            this.outsidePersonMap.put(person.getId(), person);
        }



    }
//    private List<PersonPathItem> generatePersonPathItemList(List<RouteStation> routeStations, String routeId) {
//        List<PersonPathItem> personPathItems = new ArrayList<>();
//        for (int n = 0; n < routeStations.size(); n++) {
//            PersonPathItem personPathItem = new PersonPathItem();
//            String stationId = routeStations.get(n).getStationId();
//            personPathItem.setStationId(stationId);
//
//            String name = stationNetMap.get(stationId).getName();
//            personPathItem.setStationName(name);
//            personPathItem.setIndex(n);
//            transferStationMap.forEach((k, v) -> {
//                if (v.isInTransferStation(stationId)) {
//                    personPathItem.setTransfer(true);
//                } else {
//                    personPathItem.setNeedTransfer(false);
//                }
//
//            });
//            if(routeStations.get(n).getTripDrct()==null) {
//                personPathItem.setNeedTransfer(false);
//            }else {
//                if (routeStations.get(n).getTripDrct().isEmpty()) {
//                    personPathItem.setNeedTransfer(true);
//                } else {
//                    personPathItem.setNeedTransfer(false);
//                }
//            }
//            personPathItem.setPathIndex(routeId);
//
//            personPathItems.add(personPathItem);
//
//
//        }
//        return personPathItems;
//    }

    @Override
    public void LoadPersons(int size,String stationId) {
//        System.out.println("加载历史数据");
        if(stationId.equals("0457")){
            System.out.println("debug");
        }
        Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap=odProbabilityApiInfosMapmap.get(stationId);
        loadHistoryPersons(size,odProbabilityApiInfosMap, route2PersonPathMap);

    }
}
